package enterprise.manage.dao;

import enterprise.manage.entity.Orders;
import org.apache.commons.lang.StringUtils;
import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;
import org.springside.modules.orm.hibernate.HibernateDao;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User:zhenmingyue
 * Date: 2012-11-20
 * Desc:
 */
@Repository
@Transactional
public class OrderDao extends HibernateDao<Orders, Long> {


    /**
     * @param pageNo
     * @param pageSize
     * @param queryBegin
     * @param queryEnd
     * @param userName
     * @param orderNo
     * @param consignee
     * @param queryTimeTypeId
     * @return
     */

    @SuppressWarnings("unchecked")
    public Page<Orders> getOrderPage(int pageNo, int pageSize, Calendar queryBegin, Calendar queryEnd,
                                     String orderNo, String userName, String consignee, String consigneeAddress,
                                     String consigneeMobile, String status, String logisticsOrderId,
                                     String queryTimeTypeId) {
        Criteria criteria = this.getSession().createCriteria(Orders.class);
        criteria.setCacheable(true);
        criteria.setCacheMode(CacheMode.GET);
        criteria.setCacheRegion("defaultCache");
        String queryTimeTypeName = "createTime";

        if (StringUtils.isNotBlank(queryTimeTypeId)) {
            queryTimeTypeName = TIME_TYPE.fromInt(Integer.parseInt(queryTimeTypeId)).name();
            if (queryBegin != null) {
                criteria.add(Restrictions.ge(queryTimeTypeName, queryBegin));
            }
            if (queryEnd != null) {
                criteria.add(Restrictions.lt(queryTimeTypeName, queryEnd));
            }
        }

        if (StringUtils.isNotBlank(userName)) {
            criteria.createCriteria("user").add(Restrictions.like("userName", userName, MatchMode.START));
        }

        if (StringUtils.isNotBlank(orderNo)) {
            criteria.add(Restrictions.eq("orderNo", orderNo));
        }


        if (StringUtils.isNotBlank(consignee)) {
            criteria.add(Restrictions.like("consignee", consignee, MatchMode.START));
        }

        if (StringUtils.isNotBlank(consigneeMobile)) {
            criteria.add(Restrictions.like("mobile", consigneeMobile, MatchMode.START));
        }

        if (StringUtils.isNotBlank(consigneeAddress)) {
            criteria.add(Restrictions.like("consigneeAddress", consigneeAddress, MatchMode.START));
        }
        if (StringUtils.isNotBlank(status)) {
            criteria.add(Restrictions.eq("status", status));
        }

        if (StringUtils.isNotBlank(logisticsOrderId)) {
            criteria.add(Restrictions.like("logisticsOrderId", logisticsOrderId, MatchMode.START));
        }

        criteria.addOrder(Order.desc("createTime"));
        List result = criteria.list();
        Page<Orders> page = new Page<Orders>();
        if (page.isAutoCount()) {
            int totalCount = countCriteriaResult(criteria);
            page.setTotalCount(totalCount);
        }
        page.setOrderBy(queryTimeTypeName);
        page.setOrder("desc");
        page.setPageSize(pageSize);
        page.setPageNo(pageNo);
        setPageParameter(criteria, page);

        page.setResult(result);
        return page;
    }


    public static enum TIME_TYPE {
        leaveBeginTime(1), leaveEndTime(2), createTime(3), payTime(4), shippingTime(5),
        returnTime(6), paybackTime(7), abroadTime(8);
        private int value;

        TIME_TYPE(int value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return Integer.toString(this.value);
        }

        public static TIME_TYPE fromInt(int i) {
            return TIME_TYPE.map.get(i);
        }

        private static Map<Integer, TIME_TYPE> map = new HashMap<Integer, TIME_TYPE>();

        static {
            for (TIME_TYPE p : TIME_TYPE.values()) {
                TIME_TYPE.map.put(p.value, p);
            }
        }
    }
}
